package com.eb.buybuybuy.core.router;

import com.eb.buybuybuy.annotation.RequestParameter;
import com.eb.buybuybuy.annotation.SessionParameter;
import com.eb.buybuybuy.constant.RequestMethodConstant;
import com.eb.buybuybuy.constant.RequestMethodEnum;
import com.eb.buybuybuy.core.IOC;
import com.eb.buybuybuy.core.router.bean.RequestRouteEntrance;
import com.eb.buybuybuy.result.Result;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;

@WebServlet("/api/*")
public class GlobalHttpServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");

        String method = req.getMethod();
        RequestMethodEnum requestEnum;
        if (method.equals(RequestMethodConstant.GET)) {
            requestEnum = RequestMethodEnum.GET;
        } else if (method.equals(RequestMethodConstant.POST)) {
            requestEnum = RequestMethodEnum.POST;
        } else if (method.equals(RequestMethodConstant.PUT)) {
            requestEnum = RequestMethodEnum.PUT;
        } else if (method.equals(RequestMethodConstant.DELETE)) {
            requestEnum = RequestMethodEnum.DELETE;
        } else {
            System.out.println("未知请求类型:" + method);
            resp.setStatus(405);
            return;
        }

        // 通过路由器找到路由
        RequestRouteEntrance entrance = RequestRouter.matchesRoute(requestEnum, req.getPathInfo());

        if (entrance == null) {
            System.out.println("对于 " + req.getServletPath() + req.getPathInfo() + " 请求没有匹配结果");
            return;
        }
        Method entranceMethod = entrance.getEntranceMethod();
        Class controllerClass = entrance.getControllerClass();
        Object controllerObject = entrance.getControllerObj();

        if (entranceMethod == null || controllerClass == null || controllerObject == null) {
            System.out.println("路由内部错误");
            return;
        }
        Object[] parameters = Arrays.stream(entranceMethod.getParameters()).map((parameter -> {
            // 需要session
            SessionParameter sessionParameterAnnotation = parameter.getAnnotation(SessionParameter.class);
            if (sessionParameterAnnotation != null) {
                return req.getSession();
            }

            // 需要请求参数
            RequestParameter requestParameterAnnotation = parameter.getAnnotation(RequestParameter.class);
            if (requestParameterAnnotation == null) {
                return null;
            }
            String parameterName = requestParameterAnnotation.value();
            return req.getParameter(parameterName);
        })).toArray();

        try {
            Object returnValue = entranceMethod.invoke(controllerObject, parameters);
            resp.getWriter().write(Result.success(returnValue));
        } catch (ReflectiveOperationException e) {
            System.out.println("处理 " + req.getServletPath() + req.getPathInfo() + "请求时异常：");
            e.printStackTrace();
            resp.getWriter().write(Result.error(e.getCause().getMessage()));
        }
    }
}
